package LAAMI;

import java.util.ArrayList;
import repast.simphony.context.Context;
import repast.simphony.dataLoader.ContextBuilder;
import repast.simphony.engine.environment.RunEnvironment;
import repast.simphony.random.RandomHelper;
import repast.simphony.parameter.*;

public class LAAMIBuilder implements ContextBuilder<Object> {

	private static int PATIENCE_MIN = 5;
	private static int PATIENCE_MAX = 45;
	private static double JUDGEMENT_MIN = 0.5;
	private static double JUDGEMENT_MAX = 1.5;
	private static OptionMarket optionmarket;
	private static StockMarket stockmarket;
	private static ArrayList<Investor> agentList;
	private static double initialStockPrice;
	private static double initialOptionPrice = 0;
	private static double drift;
	private static double stockVolatility;
	private static int investorCount;
	private static int endTick = 365;
	// Values for experiments: 0.25 to 1.25
	private static double maturity;
	// risk-free interest rate
	private static double interestRate = 0.03;

	@Override
	public Context build(Context<Object> context) {
		context.setId("LAAMI");

		// End simulation instance at "endTick" day
		RunEnvironment.getInstance().endAt(endTick);

		// Take the parameter given from the GUI
		Parameters userVals = RunEnvironment.getInstance().getParameters();

		// Change the values to the given parameters
		investorCount = (Integer) userVals.getValue("investorCount");
		initialStockPrice = (Float) userVals.getValue("initialStockPrice");
		drift = (Float) userVals.getValue("drift");
		stockVolatility = (Float) userVals.getValue("stockVolatility");
		interestRate = (Float) userVals.getValue("interestRate");
		setMaturity((Float) userVals.getValue("maturity"));

		// Build a StockMarket. Put it in the context.
		stockmarket = new StockMarket(initialStockPrice, stockVolatility, drift);
		context.add(stockmarket);

		// Build an OptionMarket. Put it in the context.
		optionmarket = new OptionMarket(initialOptionPrice,maturity);
		context.add(optionmarket);

		agentList = new ArrayList<Investor>();

		// Build investorCount Investors. Put them into context and AgentList.
		for (int i = 0; i < investorCount; i++) {
			int patience = RandomHelper.nextIntFromTo(PATIENCE_MIN,
					PATIENCE_MAX);
			double judgement = RandomHelper.nextDoubleFromTo(JUDGEMENT_MIN,
					JUDGEMENT_MAX);
			Investor investor = new Investor(patience, judgement,maturity);
			context.add(investor);
			agentList.add(investor);
		}
		
		return context;
	}

	/* -------------setters/getters-------------------- */
	public static OptionMarket getOptionmarket() {
		return optionmarket;
	}

	public static StockMarket getStockmarket() {
		return stockmarket;
	}

	public static ArrayList<Investor> getAgentList() {
		return agentList;
	}

	public void setAgentList(ArrayList<Investor> a) {
		agentList = a;
	}

	public static int getPATIENCE_MIN() {
		return PATIENCE_MIN;
	}

	public static void setPATIENCE_MIN(int pATIENCE_MIN) {
		PATIENCE_MIN = pATIENCE_MIN;
	}

	public static int getPATIENCE_MAX() {
		return PATIENCE_MAX;
	}

	public static void setPATIENCE_MAX(int pATIENCE_MAX) {
		PATIENCE_MAX = pATIENCE_MAX;
	}

	@Parameter(displayName = "Initial Stock Price", usageName = "initialStockPrice", defaultValue = "100", converter = "repast.simphony.parameter.StringConverterFactory$FloatConverter")
	public static double getInitialStockPrice() {
		return initialStockPrice;
	}

	public static void setInitialStockPrice(double i) {
		initialStockPrice = i;
	}

	@Parameter(displayName = "Drift", usageName = "drift", defaultValue = "0.0", converter = "repast.simphony.parameter.StringConverterFactory$FloatConverter")
	public static double getDrift() {
		return drift;
	}

	public static void setDrift(double d) {
		drift = d;
	}

	@Parameter(displayName = "Stock Volatility", usageName = "stockVolatility", defaultValue = "0.3", converter = "repast.simphony.parameter.StringConverterFactory$FloatConverter")
	public static double getStockVolatility() {
		return stockVolatility;
	}

	public static void setStockVolatility(double s) {
		stockVolatility = s;
	}

	@Parameter(displayName = "Investor Count", usageName = "investorCount", defaultValue = "50", converter = "repast.simphony.parameter.StringConverterFactory$IntConverter")
	public static int getInvestorCount() {
		return investorCount;
	}

	public static void setInvestorCount(int i) {
		investorCount = i;
	}

	public static double getMaturity() {
		return maturity;
	}

	public static void setMaturity(double maturity) {
		LAAMIBuilder.maturity = maturity;
	}

	public static double getInterestRate() {
		return interestRate;
	}

	public static void setInterestRate(double interestRate) {
		LAAMIBuilder.interestRate = interestRate;
	}

}
